package com.fasteat.menu.async;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.fasteat.common.entity.GlobalException;
import com.fasteat.common.entity.Result;
import com.fasteat.common.entity.StatusCode;
import com.fasteat.menu.entity.Menu;
import com.fasteat.menu.entity.vo.AuthorVo;
import com.fasteat.menu.entity.vo.CategoryVo;
import com.fasteat.menu.entity.vo.MenuMessageVo;
import com.fasteat.menu.entity.vo.MenuPraiseVo;
import com.fasteat.menu.mapper.CategoryMapper;
import com.fasteat.menu.mapper.MaterialMapper;
import com.fasteat.menu.mapper.MenuMapper;
import com.fasteat.menu.service.client.UserClient;
import com.fasteat.menu.util.MenuTagUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Future;

/**
 * @author run
 * @since 2021/3/8 21:46
 */
@Component
public class MenuAsync {

    @Autowired
    private MenuMapper menuMapper;

    @Autowired
    private MaterialMapper materialMapper;

    @Autowired
    private CategoryMapper categoryMapper;

    @Autowired
    private MenuTagUtil menuTagUtil;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private UserClient userClient;

    private final static String MENUKEY = "menuAllCount_";

    //设置菜谱的标签
    @Async("asyncTaskExecutor")
    public void setTagOfMenu(Menu menu){
        String menuTag = menuTagUtil.getMenuTag(menu.getMenuTitle(), menu.getMenuContext());

        UpdateWrapper<Menu> wrapper = new UpdateWrapper<>();
        wrapper.eq("id",menu.getId())
                .set("menu_tag",menuTag);

        menuMapper.update(menu,wrapper);
    }

    //redis推送更新数据库里的数据
    @Async("asyncTaskExecutor")
    public void updateMenuMessage(MenuMessageVo menu){
        UpdateWrapper<Menu> wrapper = new UpdateWrapper<>();
        wrapper.eq("id",menu.getMenuId())
                .set(menu.getMenuCollect() > 0,"menu_collect",menu.getMenuCollect())
                .set(menu.getMenuComment() > 0,"menu_comment",menu.getMenuComment())
                .set(menu.getMenuPraise() > 0,"menu_praise",menu.getMenuPraise())
                .set(menu.getMenuView() > 0,"menu_view",menu.getMenuView());
        menuMapper.update(new Menu(),wrapper);
    }

    //删除菜谱的用料信息
    @Async("asyncTaskExecutor")
    public void removeMaterialOfMenu(String menuId){
        materialMapper.removeMaterialOfMenu(menuId);
    }


    //异步递归获取子分类
    @Async("asyncTaskExecutor")
    public void getChildCategory(CategoryVo parentCategory, CountDownLatch count){
        String parentId = parentCategory.getId();
        List<CategoryVo> category = categoryMapper.getChildCategoryOfParentId(parentId);
        parentCategory.setChildrens(category);

        CountDownLatch childCount = new CountDownLatch(category.size());

        category.forEach((childCategory) -> {
            getChildCategory(childCategory,childCount);
        });

        try {
            childCount.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        count.countDown();
    }

    @Async("asyncTaskExecutor")
    public void updateMenuPraise(MenuPraiseVo menu, CountDownLatch count){
        String key = MENUKEY + menu.getId();
        if (redisTemplate.hasKey(key)){
            menu.setMenuPraise(Integer.valueOf((String) redisTemplate.opsForList().index(key, 0)));
        }
        count.countDown();
    }

    @Async("asyncTaskExecutor")
    public Future<AuthorVo> getAuthorOfMenu(String authorId){
        ArrayList<String> list = new ArrayList<>(1);
        list.add(authorId);
        Result authorVos = userClient.getAuthorVos(list);

        if (authorVos.getStatusCode() != StatusCode.OK.getCode()){
            throw new GlobalException(StatusCode.ERROR, "获取失败");
        }

        List<AuthorVo> result = JSON.parseArray(JSON.toJSONString(authorVos.getData()), AuthorVo.class);

        return new AsyncResult<>(CollectionUtils.isEmpty(result) ? null : result.get(0));
    }
}
